local sz_wuxing = fk.CreateSkill {
  name = "sz_wuxing",
  tags = { Skill.Compulsory },
}

local cardMark = "@sz_wuxing"
local playerMark = "@[sz_wuxing]"

Fk:loadTranslationTable {
  ["sz_wuxing"] = "五行",
  [":sz_wuxing"] = "游戏开始时，你从“金木水火土”选择一个属性且你获得的牌随机获得“金木水火土”的属性附加，若你使用的牌与自身属性：" ..
      "<br>相同，则你摸一张牌并将自身属性转化至下一个相生属性；" ..
      "<br>不同，则弃置一张牌并将自身属性转化至下一个相克属性。",

  ["$sz_wuxing1"] = "寒风凌冽，若风刀霜剑，有祸者难全其身。",
  ["$sz_wuxing2"] = "瑞雪漫天，兆丰年足粟，有福者可保安泰。",

  ["@[:]sz_wuxing"] = "五行效果一览",
  ["sz_jin"] = "金",
  [":sz_jin"] = "<br>属性：每回合首次造成的伤害+1<br>卡牌：使用时选择不可响应或伤害+1",
  ["sz_mu"] = "木",
  [":sz_mu"] = "<br>属性：摸牌阶段摸牌数+2手牌上限+3<br>卡牌：失去此牌时摸一张牌且本回合手牌上限+1",
  ["sz_shui"] = "水",
  [":sz_shui"] = "<br>属性：结束阶段恢复一点体力<br>卡牌：使用或打出时恢复一点体力",
  ["sz_huo"] = "火",
  [":sz_huo"] = "<br>属性：每回合第一张牌无次数距离限制<br>卡牌：使用时无次数距离限制",
  ["sz_tu"] = "土",
  [":sz_tu"] = "<br>属性：每回合首次受到的伤害-1<br>卡牌：失去此牌后，若你的护甲为0，获得一点护甲",

  ["jin_damage"] = "伤害加一",
  ["jin_ex"] = "不可响应",

  ["sz_card_effect"] = "卡牌效果",
  ["card:sz_jin"] = "使用时选择不可响应或伤害+1",
  ["card:sz_mu"] = "失去此牌时摸一张牌且本回合手牌上限+1",
  ["card:sz_shui"] = "使用或打出时恢复一点体力",
  ["card:sz_huo"] = "使用时无次数距离限制",
  ["card:sz_tu"] = "失去此牌后，若你的护甲为0，获得一点护甲",

  ["sz_player_effect"] = "角色效果",
  ["player:sz_jin"] = "每回合首次造成的伤害+1",
  ["player:sz_mu"] = "摸牌阶段摸牌数+2手牌上限+3",
  ["player:sz_shui"] = "结束阶段恢复一点体力",
  ["player:sz_huo"] = "每回合第一张牌无次数距离限制",
  ["player:sz_tu"] = "每回合首次受到的伤害-1",


  ["#sz_wuxing-choose-nature"] = "请选择你的五行属性",
  [playerMark] = "五行",
  [cardMark] = "", -- 留空
  [""] = "",
  [""] = "",
  [""] = "",
  [""] = "",
}
-- 相生顺序
local nature_list = { "sz_jin", "sz_shui", "sz_mu", "sz_huo", "sz_tu" }

-- 相克顺序
local nature_relist = { "sz_jin", "sz_mu", "sz_tu", "sz_shui", "sz_huo" }

--- 获得下一个相生属性
---@param nature string
---@return string?
local nextNature = function(nature)
  local index = table.indexOf(nature_list, nature)
  if index < 1 then return nil end
  index = index + 1
  return nature_list[index] or nature_list[index - 5]
end

--- 获得下一个相克属性
---@param nature string
---@return string?
local nextReNature = function(nature)
  local index = table.indexOf(nature_list, nature)
  if index < 1 then return nil end
  index = index + 2 -- 相克其实就是相生顺序+2
  return nature_list[index] or nature_list[index - 5]
end

sz_wuxing:addEffect(fk.GameStart, {
  anim_type = "special",
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(sz_wuxing.name)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:setBanner("@[:]sz_wuxing", nature_list)
    local result = room:askToCustomDialog(player, {
      skill_name = sz_wuxing.name, -- focus text
      qml_path = "packages/MahjongSoul/qml/AskForNatureBox.qml",
      extra_data = {}
    })
    if not table.contains(nature_list, result) then
      result = table.random(nature_list)
    end
    room:setPlayerMark(player, playerMark, result)
    -- 初始手牌也加上标记
    for _, id in ipairs(player:getCardIds("h")) do
      room:setCardMark(Fk:getCardById(id), cardMark, table.random(nature_list))
    end
  end,
})

--- 获得牌时，附加属性给牌
sz_wuxing:addEffect(fk.AfterCardsMove, {
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(sz_wuxing.name) then return false end
    for _, move in ipairs(data) do
      if (move.to == player and move.toArea == Card.PlayerHand) then
        return true
      end
      --木土
      --木卡牌失去时增加一点手牌上限并摸一张牌
      --土卡牌失去时增加一点护甲
      if move.from == player then
        local qrzmark = { "sz_mu", "sz_tu" }
        for _, info in ipairs(move.moveInfo) do
          local id = Fk:getCardById(info.cardId)
          if info.fromArea == Card.PlayerHand and table.contains(qrzmark, id:getMark(cardMark)) then
            return true
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local hand = player:getCardIds("h")
    for _, move in ipairs(data) do
      if (move.to == player and move.toArea == Card.PlayerHand) then
        for _, info in ipairs(move.moveInfo) do
          local id = info.cardId
          if table.contains(hand, id) then
            room:setCardMark(Fk:getCardById(id), cardMark, table.random(nature_list))
          end
        end
      end
      --木土
      --木卡牌失去时增加一点手牌上限并摸一张牌
      --土卡牌失去此牌后，若你的护甲为0，获得一点护甲
      if move.from == player then
        local qrzmark = { "sz_mu", "sz_tu" }
        for _, info in ipairs(move.moveInfo) do
          local id = Fk:getCardById(info.cardId)
          if info.fromArea == Card.PlayerHand and table.contains(qrzmark, id:getMark(cardMark)) then
            if id:getMark(cardMark) == "sz_mu" then
              player:drawCards(1, sz_wuxing.name)
              room:addPlayerMark(player, MarkEnum.AddMaxCardsInTurn, 1)
            else
              if player.shield == 0 then
                room:changeShield(player, 1)
              else
                return
              end
            end
          end
        end
      end
    end
  end,
})


--- 使用牌时，改变自身属性
sz_wuxing:addEffect(fk.CardUsing, {
  anim_type = "special",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(sz_wuxing.name) and target == player and player:getMark(playerMark) ~= 0 then
      local mark = data.card:getMark(cardMark)
      return mark ~= 0
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    --此处添加使用时触发的效果
    --金
    --金卡牌使用时无法相应或伤害+1，此处需判断卡牌类型是否能被加伤，不能则必定无法响应
    if data.card:getMark(cardMark) == "sz_jin" and (data.card.sub_type ~= Card.SubtypeDelayedTrick) then
      local chs = { "jin_damage", "jin_ex" }
      local disrespon = false
      if data.card.is_damage_card then
        local chc = room:askToChoice(player, { choices = chs, all_choice = chs, skill_name = sz_wuxing.name })
        if chc == "jin_damage" then
          data.additionalDamage = (data.additionalDamage or 0) + 1
        elseif chc == "jin_ex" then
          disrespon = true
        end
      end
      if not data.card.is_damage_card or disrespon == true then
        data.disresponsiveList = table.simpleClone(player.room.players)
      end
    end
    --水
    --水卡牌使用或打出时回复一点体力
    if data.card:getMark(cardMark) == "sz_shui" then
      if player:isWounded() then
        room:recover({
          who = player,
          num = 1,
          recoverBy = player,
          skillName = sz_wuxing.name,
        })
      end
    end
    local nature
    -- 相同属性，转相生属性
    if data.card:getMark(cardMark) == player:getMark(playerMark) then
      player:drawCards(1, sz_wuxing.name)
      nature = nextNature(player:getMark(playerMark))
    else -- 不同属性，转相克属性
      room:askToDiscard(player,
        { min_num = 1, max_num = 1, include_equip = true, skill_name = sz_wuxing.name, cancelable = false })
      nature = nextReNature(player:getMark(playerMark))
    end
    if player.dead then return end
    if nature then
      room:setPlayerMark(player, playerMark, nature)
    end
  end,
})


Fk:addQmlMark {
  name = "sz_wuxing",
  qml_path = "packages/MahjongSoul/qml/NatureMarkBox",
  how_to_show = function(name, value, p)
    if type(value) == "string" then
      return Fk:translate(value)
    end
    return " "
  end,
}

--金属性
--金属性每回合首次造成伤害+1
sz_wuxing:addEffect(fk.DamageCaused, {
  anim_type = "offensive",
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(sz_wuxing.name) and player:getMark(playerMark) == "sz_jin" and
        player:usedEffectTimes(self.name, Player.HistoryTurn) == 0
  end,
  on_use = function(self, event, target, player, data)
    data:changeDamage(1)
  end,
})
--木属性
--木属性摸牌阶段多摸两张牌且本回合手牌上限+3
sz_wuxing:addEffect(fk.DrawNCards, {
  anim_type = "drawcard",
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(sz_wuxing.name) and player:getMark(playerMark) == "sz_mu"
  end,
  on_use = function(self, event, target, player, data)
    data.n = data.n + 2
    player.room:addPlayerMark(player, MarkEnum.AddMaxCardsInTurn, 3)
  end,
})
--水属性
--水属性结束阶段回复一点体力
sz_wuxing:addEffect(fk.EventPhaseStart, {
  name = "sz_wuxing",
  anim_type = "support",
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(sz_wuxing.name) and player:getMark(playerMark) == "sz_shui" and
        player.phase == Player.Finish and player:isWounded()
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:recover({
      who = player,
      num = 1,
      recoverBy = player,
      skillName = sz_wuxing.name,
    })
  end,
})
--火属性
--火属性第一张牌不计入次数且无距离限制
sz_wuxing:addEffect(fk.PreCardUse, {
  anim_type = "offensive",
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(sz_wuxing.name) and player:getMark(playerMark) == "sz_huo" and
        player:usedEffectTimes(self.name, Player.HistoryTurn) == 0
  end,
  on_use = function(self, event, target, player, data)
    player.room:setPlayerMark(player, "fire_card-turn", 1)
    data.extraUse = true
  end,
})
--土属性
--土属性每回合首次受到伤害-1
sz_wuxing:addEffect(fk.DamageInflicted, {
  anim_type = "offensive",
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(sz_wuxing.name) and player:getMark(playerMark) == "sz_tu" and
        player:usedEffectTimes(self.name, Player.HistoryTurn) == 0
  end,
  on_use = function(self, event, target, player, data)
    data:changeDamage(-1)
  end,
})


--水
--水卡牌使用或打出时回复一点体力
sz_wuxing:addEffect(fk.CardResponding, {
  anim_type = "special",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(sz_wuxing.name) and target == player and player:getMark(playerMark) ~= 0 then
      local mark = data.card:getMark(cardMark)
      return mark == "sz_shui" and player:isWounded()
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:recover({
      who = player,
      num = 1,
      recoverBy = player,
      skillName = sz_wuxing.name,
    })
  end
})

sz_wuxing:addEffect("targetmod", {
  bypass_times = function(self, player, skill, scope, card, to)
    if player:hasSkill(sz_wuxing.name) then
      --火
      --火卡牌无次数和距离限制
      if card:getMark(cardMark) == "sz_huo" and card then
        return true
      end
    end
  end,
  bypass_distances = function(self, player, skill, card, to)
    --火属性
    --火属性 首张牌无次数和距离限制
    if player:hasSkill(sz_wuxing.name) then
      if card:getMark(cardMark) == "sz_huo" and card then
        return true
      end
      if player:getMark(playerMark) == "sz_huo" and player:getMark("fire_card-turn") == 0 then
        return card
      end
    end
  end,
})


return sz_wuxing
